import {useCursor, useGLTF} from '@react-three/drei'
import {useAtom} from 'jotai'
import {mapAtom} from './SocketManager.jsx'
import {useEffect, useMemo, useState} from 'react'
import {SkeletonUtils} from 'three-stdlib'
import {useGrid} from '../hooks/useGrid.jsx'
import {buildModeAtom} from './UI.jsx'

/**
 * 房间物品
 * @param item 物品属性对象，后端传递
 * @param onClick 点击事件
 * @param isDragging 是否当前拖动物品
 * @param draggedPos 当前拖拽位置 v3
 * @param canDrag 是否可以拖拽
 * @returns {JSX.Element}
 * @constructor
 */
export const GoodsItem = (
  {
    item,
    onClick,
    isDragging,
    draggedPos,
    draggedRotation,
    canDrag,
  }
) => {
  const {name, size, position, rotation: itemRotation} = item
  // 旋转角度根据是否拖拽判断取不同值，是拖拽物体则取拖拽角度
  const rotation = isDragging ? draggedRotation : itemRotation

  const {gridToV3} = useGrid()

  // console.log(item.name)
  // console.log('position => ', position)
  const [map, setMap] = useAtom(mapAtom)

  const {girdSpace} = map
  // console.log(size, gird.size)

  const width = (rotation === 1 || rotation === 3) ? size[1] : size[0]
  const height = (rotation === 1 || rotation === 3) ? size[0] : size[1]
  // const x = width / girdSpace / 2 + position[0] / girdSpace
  // const z = height / girdSpace / 2 + position[1] / girdSpace
  // 可以让物品随鼠标移动
  const pos = gridToV3(
    isDragging ? (draggedPos || position) : position
    , width, height)

  // console.log(x, z)
  const {scene} = useGLTF(`/models/items/${name}.glb`)

  // Skinned meshes cannot be re-used in threejs without cloning them
  const clone = useMemo(
    () => SkeletonUtils.clone(scene), [scene]
  )

  // [x, isDragging ? 0.1 : 0, z]

  // 定义是否悬停
  const [hover, setHover] = useState(false)
  const [buildMode, setBuildMode] = useAtom(buildModeAtom)

  // 构建模式下鼠标显示小手
  useCursor(buildMode ? hover : undefined)

  // 物体添加阴影
  useEffect(() => {
    clone.traverse((child) => {
      if (child.isMesh) {
        child.castShadow = true
        child.receiveShadow = true
      }
    })
  }, [])

  return (
    <group onClick={onClick} position={pos}
           onPointerEnter={() => setHover(true)}
           onPointerLeave={() => setHover(false)}
    >
      {/* 如果当前物品是被拖拽物品，显示底部拖拽表示平面 */}
      {
        isDragging && (
          <mesh>
            <boxGeometry
              args={[
                width / girdSpace,
                0.2,
                height / girdSpace
              ]}
            />
            <meshBasicMaterial
              color={canDrag ? 'green' : 'red'}
              opacity={0.3}
              transparent
            />
          </mesh>
        )
      }
      <primitive object={clone}
                 rotation-y={(rotation || 0) * Math.PI * 0.5}
      />
    </group>
  )
}
